import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.*;

import java.io.File;
import java.util.Arrays;

public class useR_injava {

    static double[][] Confusion;
    static String[] Precision;
    static Double Accuracy;
    static Integer bestK;
    static String location, kmean_location;
    public static void main(String[] args) {
        try {
            RConnection reconnect = new RConnection("127.0.0.1");

            REXP x = reconnect.eval("R.version.string");
            System.out.println(x.asString());

            //依赖
            reconnect.eval("library(factoextra)\n" +
                    "library(NbClust)\n" +
                    "library(class)\n" +
                    "library(caret)\n" +
                    "library(lattice)\n" +
                    "library(ggplot2)\n" +
                    "library(randomForest)\n" +
                    "library(plyr)\n" +
                    "library(e1071)");
            reconnect.eval("setwd(\"D:\")");

            //读取文件
            File file1 = new File("data.csv");
            location = String.valueOf(file1.getAbsoluteFile());
            String[] sd = new String[1];
            sd[0] = "\\";
            location = detection(location,sd);
//            System.out.println(location);
            reconnect.eval("dd <- read.table('" + location + "', header = T, sep = \",\")");

            //k-fold
            reconnect.eval("set.seed(1234)\n" +
                    "index_dd <- createDataPartition(dd$UNS, p=0.80, list = F, times = 1)\n" +
                    "df_dd <- as.data.frame(dd)\n" +
                    "train_df_dd <- df_dd[index_dd,]\n" +
                    "test_df_dd <- df_dd[-index_dd,]");

            reconnect.eval("ctrlspecs_dd <- trainControl(method = \"cv\", number = 10,\n" +
                    "                    savePredictions = \"all\")");
            reconnect.eval("set.seed(1234)");
            reconnect.eval("model1_dd <- train(UNS ~ .,\n" +
                    "                data = train_df_dd,\n" +
                    "                method = \"knn\", \n" +
                    "                trControl = ctrlspecs_dd)");
            bestK = reconnect.eval("model1_dd$finalModel$k").asInteger();

           //get the Precision (exactness of a mode) in all 3 kinds of K
            reconnect.eval("results_dd <- model1_dd$results");
            Precision =  reconnect.eval("results_dd[,1]").asStrings();
            String[] colnames = reconnect.eval("results_dd[,2]").asStrings();


            //knn
            reconnect.eval("set.seed(1234)\n" +
                    "idx <- sample(2, nrow(dd),replace = T, prob = c(0.80,0.20))\n" +
                    "dd.trainSet <- dd[idx==1, 1:5]\n" +
                    "dd.testSet <- dd[idx==2, 1:5]\n" +
                    "dd.trainLabels <- dd[idx==1, 6]\n" +
                    "dd.testLabels <- dd[idx==2, 6]");
            reconnect.eval("dd_pred <- knn(train = dd.trainSet, test = dd.testSet, cl = dd.trainLabels, k=" + bestK +")");
            Confusion = reconnect.eval("confusionTable_dd <- print(table(dd_pred, dd.testLabels))").asDoubleMatrix();
            Accuracy = reconnect.eval("accuracy_dd <- (sum(diag(confusionTable_dd))/sum(confusionTable_dd))").asDouble();

//          reconnect.eval("");
            //k-means
            //剪辑后的相对位置
            File file2 = new File("data2.csv");
            kmean_location = String.valueOf(file2.getAbsoluteFile());
            kmean_location = detection(kmean_location,sd);
            reconnect.eval("ddforkmeans <- read.table('" + kmean_location + "', header = T, sep = \",\")");
            reconnect.eval("ddforkmeans.4means <- kmeans(ddforkmeans, centers = 4)");
            reconnect.eval("jpeg(file = \"STG_STR.jpeg\")\n" +
                    "plot(dd[c(\"STG\",\"STR\")], col = ddforkmeans.4means$cluster)\n" +
                    "dev.off()\n" +
                    "\n" +
                    "jpeg(file = \"LPR_PEG.jpeg\")\n" +
                    "plot(dd[c(\"LPR\",\"PEG\")], col = ddforkmeans.4means$cluster)\n" +
                    "dev.off()");

            System.out.println("The best K for knn is:");
            System.out.println(bestK);
            System.out.println("K = " + bestK + ", the knn model accuracy and the Confusion matrix data");
            System.out.println(Accuracy);
            for (int i = 0; i < Confusion.length; i++) {
                System.out.println(Arrays.toString(Confusion[i]));
            }
            System.out.println("The Precision (exactness of knn) in 3 kinds of K");
            System.out.println(Arrays.toString(Precision));
            System.out.println(Arrays.toString(colnames));
        } catch (RserveException | REXPMismatchException e) {
            e.printStackTrace();
        }
    }

    public static String detection(String content,String[] badString){
        for (int i = 0; i <badString.length ; i++) {
            content= index(content,badString[i]);
        }
        return content;
    }

    private static String index(String content,String badString){
        if(content.equals("")||badString.equals("")){
            return content;
        }
        int index = content.indexOf(badString);
        String newString="";
        if(index!=-1){
            String newString1=content.substring(0,index);
            String newString2=content.substring(index+badString.length());
            String hindString="";
            for (int i = 0; i < badString.length() ; i++) {
                hindString = hindString + "//";
            }
            newString = newString1 + hindString + newString2;
            return index(newString,badString);
        }
        return content;
    }
}